package com.lanyuan.thrid.wechat.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.util.EntityUtils;
import org.apache.poi.ss.formula.functions.T;

import com.lanyuan.thrid.wechat.utils.JSONUtil;
import com.lanyuan.thrid.wechat.utils.XMLConverUtil;

public class LocalHttpClient {

	protected static HttpClient httpClient = HttpClientFactory.createHttpClient(100, 10);

	private static Map<String, HttpClient> httpClient_mchKeyStore = new HashMap<String, HttpClient>();

	public static void init(int maxTotal, int maxPerRoute) {
		httpClient = HttpClientFactory.createHttpClient(maxTotal, maxPerRoute);
	}

	/**
	 * 初始化 MCH HttpClient KeyStore
	 * 
	 * @param keyStoreName keyStore 名称
	 * @param keyStoreFilePath 私钥文件路径
	 * @param mch_id
	 * @param maxTotal
	 * @param maxPerRoute
	 */
	public static void initMchKeyStore(String keyStoreName, String keyStoreFilePath, String mch_id, int maxTotal,
			int maxPerRoute) {
		try {
			KeyStore keyStore = KeyStore.getInstance(keyStoreName);
			FileInputStream instream = new FileInputStream(new File(keyStoreFilePath));
			keyStore.load(instream, mch_id.toCharArray());
			instream.close();
			HttpClient httpClient = HttpClientFactory.createKeyMaterialHttpClient(keyStore, mch_id,
					new String[] { "TLSv1" }, maxTotal, maxPerRoute);
			httpClient_mchKeyStore.put(mch_id, httpClient);
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static HttpResponse execute(HttpUriRequest request) {
		try {
			return httpClient.execute(request);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static <T> T execute(HttpUriRequest request, ResponseHandler<T> responseHandler) {
		try {
			return httpClient.execute(request, responseHandler);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 数据返回自动JSON对象解析
	 * 
	 * @param request
	 * @param clazz
	 * @return
	 */
	public static Map<String, String> executeJsonResult(HttpUriRequest request) {
		try {
			return httpClient.execute(request, new ResponseHandler<Map<String, String>>() {
				public Map<String, String> handleResponse(HttpResponse response) throws ClientProtocolException,
						IOException {
					int status = response.getStatusLine().getStatusCode();
					if ((status >= 200) && (status < 300)) {
						HttpEntity entity = response.getEntity();
						String str = EntityUtils.toString(entity);
						return JSONUtil.jsonStr2Model(new String(str.getBytes("iso-8859-1"), "utf-8"), Map.class);
					} else {
						throw new ClientProtocolException("Unexpected response status: " + status);
					}
				}
			});
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 数据返回自动XML对象解析
	 * 
	 * @param request
	 * @param clazz
	 * @return
	 */
	public static Map<String, String> executeXmlResult(HttpUriRequest request) {
		try {
			return httpClient.execute(request, new ResponseHandler<Map<String, String>>() {
				public Map<String, String> handleResponse(HttpResponse response) throws ClientProtocolException,
						IOException {
					int status = response.getStatusLine().getStatusCode();
					if ((status >= 200) && (status < 300)) {
						HttpEntity entity = response.getEntity();
						String str = EntityUtils.toString(entity);
						return XMLConverUtil.convertToMap(new String(str.getBytes("iso-8859-1"), "utf-8"));
					} else {
						throw new ClientProtocolException("Unexpected response status: " + status);
					}
				}
			});
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * MCH keyStore 请求 数据返回自动XML对象解析
	 * 
	 * @param mch_id
	 * @param request
	 * @param clazz
	 * @return
	 */
	public static Map<String, String> keyStoreExecuteXmlResult(String mch_id, HttpUriRequest request, Class<T> clazz) {
		try {
			return httpClient_mchKeyStore.get(mch_id).execute(request, new ResponseHandler<Map<String, String>>() {
				public Map<String, String> handleResponse(HttpResponse response) throws ClientProtocolException,
						IOException {
					int status = response.getStatusLine().getStatusCode();
					if ((status >= 200) && (status < 300)) {
						HttpEntity entity = response.getEntity();
						String str = EntityUtils.toString(entity);
						return XMLConverUtil.convertToMap(new String(str.getBytes("iso-8859-1"), "utf-8"));
					} else {
						throw new ClientProtocolException("Unexpected response status: " + status);
					}
				}
			});
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
